package com.hs.live.user.service;

import com.alibaba.nacos.shaded.com.google.common.base.Strings;
import com.hs.live.common.enums.ErrorCodeResp;
import com.hs.live.common.redis.key.SmsRedisKeyGenerate;
import com.hs.live.common.redis.utils.RedisLiveUtil;
import com.hs.live.user.dto.CheckSmsDTO;
import com.hs.live.user.entity.SmsDO;
import com.hs.live.user.mapper.SmsMapper;
import com.hs.live.user.req.MobileLoginUserReq;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

/**
 * @Description: 发送短信服务
 * @Author 胡尚
 * @Date: 2024/9/6 17:38
 */
@Slf4j
@Service
public class SmsService {

    @Autowired
    SmsRedisKeyGenerate smsRedisKeyGenerate;

    @Autowired
    RedisLiveUtil redisLiveUtil;

    @Autowired
    SmsMapper smsMapper;

    public boolean sendSms(String phone) {
        // 参数校验
        if (Strings.isNullOrEmpty(phone)){
            return false;
        }


        // 检查redis中是否还存在数据
        String smsCheckKey = smsRedisKeyGenerate.getSmsCheckKey(phone);
        if (redisLiveUtil.hasKey(smsCheckKey)){
            log.info("{}手机号重复发送短信验证码", phone);
            return false;
        }

        // 生成短信验证码
        int smsCheck = ThreadLocalRandom.current().nextInt(1000, 9999);

        // 发送短信
        boolean sendResult = doSendSms(phone, smsCheck);
        if (!sendResult){
            log.error("{}手机号发送短信失败",phone);
            return false;
        }

        // 将验证码存入redis中，过期时间设置两分钟
        log.info("{}手机号生成的短信验证码{}",phone, smsCheck);
        redisLiveUtil.set(smsCheckKey, String.valueOf(smsCheck), 2, TimeUnit.MINUTES);

        // 将发送短信记录在DB中保存一份
        insertToDB(phone,smsCheck);

        return true;
    }

    /**
     * 在DB中生成一条发送短信记录
     * @param phone 手机号
     */
    private void insertToDB(String phone, int smsCheck) {
        SmsDO smsDO = new SmsDO();
        smsDO.setPhone(phone);
        smsDO.setCode(smsCheck);
        smsDO.setSendTime(new Date());
        smsMapper.insert(smsDO);
    }

    /**
     * 发送短信验证码
     * @param phone 手机号
     * @param smsCheck 验证码
     * @return 是否发送成功
     */
    private boolean doSendSms(String phone, int smsCheck) {
        // TODO 调用短信平台发送短信验证码
        return true;
    }

    /**
     *  校验短信验证码是否正确
     */
    public CheckSmsDTO checkSms(MobileLoginUserReq req) {
        CheckSmsDTO result = new CheckSmsDTO();

        // 短信验证码是否失效，有效期2分钟
        String redisKey = smsRedisKeyGenerate.getSmsCheckKey(req.getMobile());
        if (!redisLiveUtil.hasKey(redisKey)){
            log.info("{}手机号的短信验证码已过期", req.getMobile());
            result.setCorrect(false);
            result.setErrorCode(ErrorCodeResp.CHECK_SMS_LOGIN_INVAILD.getCode());
            return result;
        }

        // 验证码是否正确
        String smsCheckRedis = redisLiveUtil.get(redisKey);
        if (!Objects.equals(smsCheckRedis, req.getCode())){
            log.info("{}手机号的短信验证码不正确", req.getMobile());
            result.setCorrect(false);
            result.setErrorCode(ErrorCodeResp.CHECK_SMS_LOGIN_UNEQUAL.getCode());
            return result;
        }

        // 短信验证码校验通过
        log.info("{}手机号的短信验证码校验通过", req.getMobile());
        redisLiveUtil.delete(redisKey);
        result.setCorrect(true);
        return result;
    }
}
